package com.yy.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;

import com.yy.common.constant.PmsConstants;
import com.yy.common.exception.ServiceException;
import com.yy.common.utils.DateUtils;
import com.yy.common.utils.SecurityUtils;
import com.yy.common.utils.StringUtils;
import com.yy.domain.*;
import com.yy.dto.PayContractAddDTO;
import com.yy.dto.PayContractQueryDTO;
import com.yy.mapper.*;
import com.yy.service.IPayContractService;
import com.yy.system.service.ISysConfigService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Indexed;
import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 出租出售合同Service业务层处理
 *
 * @author leige
 * @date 2023-10-30
 */
@Service
public class PayContractServiceImpl implements IPayContractService
{

    @Resource
    private PayContractMapper payContractMapper;

    @Resource
    private PayContractFeeMapper payContractFeeMapper;

    @Resource
    private ISysConfigService configService;

    @Resource
    private AssetHouseMapper assetHouseMapper;

    @Resource
    private OwnerUserMapper ownerUserMapper;

    @Resource
    private PayFeeItemMapper payFeeItemMapper;

    /**
     * 新增出租出售合同
     *
     * @param payContractAddDTO 出租出售合同
     * @return 结果
     */
    @Override
    @Transactional
    public int insertPayContract(PayContractAddDTO payContractAddDTO)
    {
        //取出合同类型
        String contractType = payContractAddDTO.getContractType();
        //更新商铺状态---空置-->已出租/已出售
        Long houseId = payContractAddDTO.getHouseId();
        AssetHouse assetHouse = assetHouseMapper.selectAssetHouseById(houseId);
        if (ObjectUtils.isEmpty(assetHouse)) {
            throw new ServiceException("当前商铺不存在");
        }
        if(!assetHouse.getState().equals(PmsConstants.HOUSE_TYPE_EMPTY)){
            throw new ServiceException("当前商品状态不允许租售");
        }
        //设置业主ID  业主公司名  合同结束时间
        assetHouse.setOwnerId(payContractAddDTO.getOwnerId());
        assetHouse.setStateCompany(payContractAddDTO.getOwnerCompany());
        //计算结束时间  在开始时间的基础+合同周期个月
        Date beginDate = payContractAddDTO.getBeginDate();
        assetHouse.setStateEndTime(null);//长期
        assetHouse.setRentFee(null);
        if(contractType.equals(PmsConstants.PAY_CONTRACT_TYPE_RENTED)){
            Date endDate= DateUtil.offsetMonth(beginDate, Integer.valueOf(payContractAddDTO.getPeriod()));
            assetHouse.setRentFee(payContractAddDTO.getRentFee());
            assetHouse.setStateEndTime(endDate);
        }
        assetHouse.setState(payContractAddDTO.getContractType());
        //更新
        this.assetHouseMapper.updateAssetHouse(assetHouse);

        //处理业主出租数量和拥有数据
        OwnerUser ownerUser = this.ownerUserMapper.selectOwnerUserById(payContractAddDTO.getOwnerId());
        if(ObjectUtils.isEmpty(ownerUser)){
            throw new ServiceException("当前业主不存在");
        }
        if(contractType.equals(PmsConstants.PAY_CONTRACT_TYPE_RENTED)){
            ownerUser.setRentedCount(ownerUser.getRentedCount()+1);
        }else{
            ownerUser.setOwnCount(ownerUser.getOwnCount()+1);
        }
        //更新
        this.ownerUserMapper.updateOwnerUser(ownerUser);
        //先保存合同表
        PayContract contract=new PayContract();
        //拷贝
        BeanUtils.copyProperties(payContractAddDTO,contract);
        //设置合同编号
        String prefix = configService.selectConfigByKey(PmsConstants.PREFIX_CONTRACT_HT);
        if (StringUtils.isEmpty(prefix)) {
            throw new ServiceException("合同编号前缀没有配置");
        }
        contract.setCode(prefix+ IdUtil.getSnowflakeNextIdStr());
        contract.setEndDate(null);
        if(contractType.equals(PmsConstants.PAY_CONTRACT_TYPE_RENTED)){
            Date endDate= DateUtil.offsetMonth(beginDate, Integer.valueOf(payContractAddDTO.getPeriod()));
            contract.setEndDate(endDate);
        }
        //状态
        contract.setState(PmsConstants.PAY_CONTRACT_STATE_1);//正常
        contract.setCreateTime(DateUtils.getNowDate());
        contract.setCreateBy(SecurityUtils.getUsername());
        contract.setUpdateTime(DateUtils.getNowDate());
        contract.setUpdateBy(SecurityUtils.getUsername());
        int row = payContractMapper.insertPayContract(contract);
        //上面执行完，代表合同信息正常保存到的数据pay_contract
        Long contractId = contract.getId();
        Integer[] contractFeeIds = payContractAddDTO.getContractFeeIds();
        if(contractFeeIds==null||contractFeeIds.length==0){
            throw new ServiceException("当前合同没有收费项目，不合法");
        }
        for (Integer contractFeeId : contractFeeIds) {
            PayContractFee payContractFee=new PayContractFee();
            payContractFee.setFeeItemId(contractFeeId.longValue());
            payContractFee.setContractId(contractId.toString());
            payContractFee.setBeginDate(beginDate);
            if(contractType.equals(PmsConstants.PAY_CONTRACT_TYPE_RENTED)){
                Date endDate= DateUtil.offsetMonth(beginDate, Integer.valueOf(payContractAddDTO.getPeriod()));
                payContractFee.setEndDate(endDate);
            }
            payContractFee.setNextBillDate(beginDate);
            payContractFee.setTimes(0L);
            payContractFee.setCreateTime(DateUtils.getNowDate());
            payContractFee.setCreateBy(SecurityUtils.getUsername());
            payContractFee.setUpdateTime(DateUtils.getNowDate());
            payContractFee.setUpdateBy(SecurityUtils.getUsername());
            this.payContractFeeMapper.insertPayContractFee(payContractFee);
        }
        return row;
    }

    /**
     * 根据商铺ID和其它条件查询合同列表
     *
     * @param payContractQueryDTO
     * @return
     */
    @Override
    public List<PayContract> listContractByHouseId(PayContractQueryDTO payContractQueryDTO) {
        List<PayContract> payContracts=this.payContractMapper.listContractByHouseId(payContractQueryDTO);
        return payContracts;
    }

    /**
     * 根据合同ID查询合同的收费项目
     *
     * @param id
     * @return
     */
    @Override
    public List<PayContractFee> listContractFeeItemByContractId(Long id) {
        //根据合同ID查询合同的收费项目
        List<PayContractFee> feeList=this.payContractFeeMapper.queryContractFeeItemByContractId(id);
        if(!CollectionUtils.isEmpty(feeList)){
//            List<Long> feeItemIds=new ArrayList<>();
//            for (PayContractFee payContractFee : feeList) {
//                feeItemIds.add(payContractFee.getFeeItemId());
//            }
            //取出所有收费项目的ID
            List<Long> feeItemIds=feeList.stream().map(item->item.getFeeItemId()).collect(Collectors.toList());
            //根据项目ID查询收费项目的数据【翻译名称】
            List<PayFeeItem> payFeeItems=payFeeItemMapper.selectPayFeeItemByIds(feeItemIds);
//            Map<Long,PayFeeItem> feeItemMap=new HashMap<>();
//            for (PayFeeItem payFeeItem : payFeeItems) {
//                feeItemMap.put(payFeeItem.getId(),payFeeItem);
//            }
            Map<Long, PayFeeItem> feeItemMap = payFeeItems.stream().collect(Collectors.toMap(PayFeeItem::getId, feeItem -> feeItem));
            //重新组装数据
            for (PayContractFee payContractFee : feeList) {
                Long feeItemId = payContractFee.getFeeItemId();
                payContractFee.setFeeItemName(feeItemMap.get(feeItemId).getName());
            }
        }
        return feeList;
    }

    /**
     * 根据合同ID撤销合同
     *
     * 更改合同状态   正常-->撤销
     * 更改商铺状态   已出租/出售--->空置
     * 更新业主的租售数量
     * @param id
     * @return
     */
    @Override
    @Transactional
    public int cancelContract(Long id) {
        //根据合同ID查询合同数据
        PayContract contract = this.payContractMapper.selectPayContractById(id);
        if(ObjectUtils.isEmpty(contract)){
            throw new ServiceException("当前合同不存在");
        }
        if (!contract.getState().equals(PmsConstants.PAY_CONTRACT_STATE_1)) {
            throw new ServiceException("当前合同状态是非【正常】，不能撤销");
        }
        contract.setState(PmsConstants.PAY_CONTRACT_STATE_2);
        //更新
        this.payContractMapper.updatePayContract(contract);
        //更改商铺状态
        AssetHouse assetHouse = this.assetHouseMapper.selectAssetHouseById(contract.getHouseId());
        assetHouse.setState(PmsConstants.HOUSE_TYPE_EMPTY);
        assetHouse.setStateEndTime(null);
        assetHouse.setOwnerId(null);
        assetHouse.setStateCompany(null);
        assetHouse.setRentFee(null);
        this.assetHouseMapper.updateAssetHouse(assetHouse);

        //更新业主的租售数量
        OwnerUser ownerUser = this.ownerUserMapper.selectOwnerUserById(contract.getOwnerId());
        if(contract.getContractType().equals(PmsConstants.PAY_CONTRACT_TYPE_RENTED)){
            ownerUser.setRentedCount(ownerUser.getRentedCount()-1);
        }else{
            ownerUser.setOwnCount(ownerUser.getOwnCount()-1);
        }
        return this.ownerUserMapper.updateOwnerUser(ownerUser);
    }

    @Override
    public List<PayFeeItem> getContractFeeItemsByContractId(Long contractId) {
        //根据合同ID查询合同数据
        PayContract contract = this.payContractMapper.selectPayContractById(contractId);
        if(contract==null){
            throw new ServiceException("当前合同编号不存在");
        }
        //合同状态必须是正常的
        if(!contract.getState().equals(PmsConstants.PAY_CONTRACT_STATE_1)){
            throw new ServiceException("当前合同编号的合同状态非【正常】");
        }
        //根据合同ID查询合同的待收费收费项Id
        List<Long> feeItemIds = this.payContractFeeMapper.queryContractFeeItemIdsByContractId(contractId);
        if (CollectionUtils.isEmpty(feeItemIds)) {
            throw new ServiceException("当前合同没有收费项目");
        }
        //根据收费项目ID查询收费项目的数据
        List<PayFeeItem> payFeeItems = this.payFeeItemMapper.selectPayFeeItemByIds(feeItemIds);
        return payFeeItems;
    }

    @Override
    public PayContract queryContractByHouseAndState(Long houseId, String payContractState1) {
        return this.payContractMapper.queryContractByHouseAndState(houseId,payContractState1);
    }


    /**
     * 查询出租出售合同
     *
     * @param id 出租出售合同主键
     * @return 出租出售合同
     */
    @Override
    public PayContract selectPayContractById(Long id)
    {
        return payContractMapper.selectPayContractById(id);
    }

    /**
     * 查询出租出售合同列表
     *
     * @param payContract 出租出售合同
     * @return 出租出售合同
     */
    @Override
    public List<PayContract> selectPayContractList(PayContract payContract)
    {
        return payContractMapper.selectPayContractList(payContract);
    }




}
